/* ***** BEGIN LICENSE BLOCK *****
 *   Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 * 
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is ThumbsDown.
 *
 * The Initial Developer of the Original Code is
 * Atte Kemppilä.
 * Portions created by the Initial Developer are Copyright (C) 2007
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 * 
 * ***** END LICENSE BLOCK ***** */


const EXPORTED_SYMBOLS = ["DownloadManager"];

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;

Cu.import("resource://gre/modules/AddonManager.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");

Cu.import("resource://thumbsdown/ThumbsDown.jsm");
Cu.import("resource://thumbsdown/util.jsm");

const STRING_BUNDLE_URI = "chrome://thumbsdown/locale/downloadmanagerservice.properties";

// download managers
const dms = {};


XPCOMUtils.defineLazyGetter(this, "_", function()
{
    return getStringBundleGetter(Services.strings.createBundle(STRING_BUNDLE_URI));
});


const DownloadManager =
{
    create: function DM_create(params, callback, error)
    {
        let name = ThumbsDown.prefs.getCharPref("downloadManager");
        
        if (name in dms)
            this._create(name, params, callback, error);
        else
        {
            let e = new Error(_("error.unknown", name));
            callLater(0, null, function() { error(e); });
        }
    },
    
    _create: function DM__create(name, params, callback, error)
    {
        // download manager is created from scratch each time
        // this is simply easier since dta3 is bootstrapped -> can be disabled/enabled anytime
        
        let self = this;
        AddonManager.getAddonByID(dms[name].id, function(addon)
        {
            try
            {
                if (addon)
                {
                    for each (let dm in dms[name].versions)
                    {
                        if (dm.prototype.id != dms[name].id)
                            throw new Error("id mismatch: " + dm.name);
                        
                        if ((Services.vc.compare(dm.prototype.minVersion, addon.version) <= 0) && 
                            (Services.vc.compare(addon.version, dm.prototype.maxVersion) <= 0))
                        {
                            if (addon.isActive)
                            {
                                let downloadManager = new dm(params);
                                try
                                {
                                    callback(downloadManager);
                                }
                                catch (e)
                                {
                                    Cu.reportError(e);
                                }
                                return;
                            }
                            else
                                throw new Error(_("error.disabled", name));
                        }
                    }
                    
                    throw new Error(_("error.incompatibleVersion", name, addon.version));
                }
                else
                    throw new Error(_("error.notInstalled", name));
            }
            catch (e)
            {
                error(e);
            }
        });
    },
}


/** DownThemAll! 2.x release version */
function DownThemAll(params)
{
    this.dir = params.dir;
    this.numInstance = this._numInstance;
    this.renameMask = ThumbsDown.prefs.getComplexValue("dm.dta.renameMask", Ci.nsISupportsString).data;
}

DownThemAll.prototype =
{
    id: "{DDC359D1-844A-42a7-9AA1-88A850A938A8}",
    minVersion: "2.0b5",
    maxVersion: "2.0.*",
    
    windowUri: "chrome://dta/content/dta/manager.xul",
    windowName: "DTA:Manager",
    windowFeatures: "chrome, centerscreen, resizable=yes, dialog=no, all, modal=no, dependent=no",
    
    _prefs: Services.prefs.getBranch("extensions.dta."),
    
    get _numInstance()
    {
        // downthemall/chrome/content/common/overlayFunctions.js:DTA_AddingFunctions.turboSendToDown()
        var num = 0;
        try { num = this._prefs.getIntPref("counter"); } catch (e) { /* ignore */ }
        num = ((num < 999) ? ++num : 1);
        this._prefs.setIntPref("counter", num);
        return num;
    },
    
    download: function(urls)
    {
        var queue = true;
        var numInstance = this.numInstance;
        // downthemall/chrome/content/common/overlayFunctions.js:DTA_AddingFunctions.saveSingleLink()
        // downthemall/chrome/content/common/overlayFunctions.js:DTA_AddingFunctions.turboSendToDown()
        var dtaUrls = [{url: url.url, dirSave: this.dir, numIstance: numInstance, mask: this.renameMask, referrer: url.referer} for each (url in urls)];
        this._start(queue, dtaUrls)
    },
    
    _start: function(queue, dtaUrls)
    {
        // downthemall/chrome/content/common/overlayFunctions.js:DTA_AddingFunctions.sendToDown()
        var win = Services.wm.getMostRecentWindow(this.windowName);
        // if window is open...
        if (win)
            // ...and initialized, use it
            if (win.self && win.self.Dialog && win.self.Dialog._initialized)
                win.self.startDownloads(queue, dtaUrls);
            else
            {
                var onLoad = function(e)
                {
                    // |this| is dta manager window
                    var startDownloads = function() { this.startDownloads(queue, dtaUrls); }
                    // 0-delay required to make sure that dta onload handler goes first
                    e.target.defaultView.setTimeout(startDownloads, 0);
                }
                win.addEventListener("load", onLoad, false);
            }
        // if window is not yet opened, open a new one
        else
        {
            var parent = null;
            var arguments = null;
            win = Services.ww.openWindow(parent, this.windowUri, this.windowName, this.windowFeatures, arguments);
            // FIXME: openWindow arguments hack
            win.arguments = [queue, dtaUrls];
        }
    }
}


/** DownThemAll! 2.x development version */
function DownThemAllDev(params)
{
    DownThemAll.call(this, params);
}

DownThemAllDev.prototype =
{
    __proto__: DownThemAll.prototype,
    
    id: "dta@downthemall.net",
    minVersion: "2.0",
    maxVersion: "2.*",
}


/** DownThemAll! 3.x release version */
function DownThemAll3(params)
{
    let glue = {};
    Cu.import("chrome://dta-modules/content/glue.jsm", glue);
    this.DTA = glue.require("api");
    
    this.dir = params.dir;
    this.numInstance = this.DTA.incrementSeries();
    this.renameMask = ThumbsDown.prefs.getComplexValue("dm.dta.renameMask", Ci.nsISupportsString).data;
}

DownThemAll3.prototype =
{
    id: "{DDC359D1-844A-42a7-9AA1-88A850A938A8}",
    minVersion: "3.0b1",
    maxVersion: "3.0.*",
    
    download: function(urls)
    {
        let window = null;
        let startDownload = true;
        let dtaUrls = [{url: url.url, dirSave: this.dir, numIstance: this.numInstance, mask: this.renameMask, referrer: url.referer} for each (url in urls)];
        
        this.DTA.sendLinksToManager(window, startDownload, dtaUrls);
    },
}


/** DownThemAll! 3.x development version */
function DownThemAll3Dev(params)
{
    DownThemAll3.call(this, params);
}

DownThemAll3Dev.prototype =
{
    __proto__: DownThemAll3.prototype,
    
    id: "dta@downthemall.net",
    minVersion: "3.0b1",
    maxVersion: "3.*",
}


dms["downthemall"]     = {id: "{DDC359D1-844A-42a7-9AA1-88A850A938A8}", versions: [DownThemAll3, DownThemAll]};
dms["downthemall_dev"] = {id: "dta@downthemall.net",                    versions: [DownThemAll3Dev, DownThemAllDev]};
